package org.helsoft.mojo.api;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

public abstract class AbstractPDEMojo extends AbstractBaseMojo {
	/**
	 * Eclipse Location.
	 * 
	 * @parameter expression="${eclipseLocation}"
	 * @required
	 */
	private File eclipseLocation;
	
	/**
	 * Manifest.
	 * 
	 * @parameter default-value="${project.basedir}/META-INF/MANIFEST.MF"
	 * @required
	 */
	protected String manifestLocation;

	/**
	 * Build properties.
	 * 
	 * @parameter default-value="${project.basedir}/build.properties"
	 */
	protected String buildPropertiesFile;

	/**
	 * Build configuration could be use to override the
	 * <code>buildPropertiesFile</code>.
	 * 
	 * @parameter
	 */
	private Properties buildProperties;

	/**
	 * If this variable is set the resolved bundle will be copied to this
	 * directory pointed by this variable, and the systemPath of the
	 * dependencies will be set according to this location. Be aware if you use
	 * an SCM such as svn, cvs or others to not commit this directory, which
	 * must be delete by the clean goal. The path provided by this variable its
	 * relative to the project basedir.
	 * 
	 * @parameter expression="${tempLibrariesLocation}"
	 */
	private String tempLibrariesLocation;

	/**
	 * The plugin descriptor from the manifest location.
	 */
	private PluginDescriptor descriptor;

	/**
	 * The file where the pde pom is generated.
	 * 
	 * @parameter default-value="pde-pom.xml"
	 */
	private File pdePom;

	/**
	 * Whether to preserve the generated PDE POM during the cleaning phase.
	 * 
	 * @parameter expression="${preservePdePom}" default-value="false"
	 */
	private Boolean preservePdePom;
	
	/**
	 * 
	 * @return The PDE Pom file
	 */
	public final File getPDEPom() {
		return pdePom;
	}
	
	/**
	 * @return the manifestLocation
	 */
	public final String getManifestLocation() {
		return manifestLocation;
	}

	/**
	 * @param manifestLocation the manifestLocation to set
	 */
	public final void setManifestLocation(String manifestLocation) {
		this.manifestLocation = manifestLocation;
	}

	/**
	 * 
	 * @return The eclipse location
	 */
	public final File getEclipseLocation() {
		return eclipseLocation;
	}
	
	/**
	 * @return the maven
	 */
	public final org.apache.maven.Maven getMaven() {
		return maven;
	}

	/**
	 * 
	 * @return The build properties
	 * @throws MojoExecutionException
	 */
	public final Properties getBuildProperties() throws MojoExecutionException {
		if (buildProperties == null) {
			Properties props = null;

			File file = buildPropertiesFile != null ? new File(
					buildPropertiesFile) : null;

			if (file != null && file.isFile()) {
				InputStream in = null;
				try {
					in = new FileInputStream(file);
					props = new Properties();
					props.load(in);
				} catch (IOException e) {
					throw new MojoExecutionException(
							"No build.properties file has been found");
				} finally {
					if (in != null) {
						try {
							in.close();
						} catch (IOException e) {
							// Ignore
						}
					}
				}
			}

			buildProperties = props;
		}

		return buildProperties;
	}

	/**
	 * 
	 * @return The descriptor of the plugin currently built
	 * @throws MojoFailureException
	 */
	public final PluginDescriptor getPluginDescriptor()
			throws MojoFailureException {
		if (descriptor == null) {
			try {
				descriptor = PluginDescriptor.fromManifest(new File(
						manifestLocation));
			} catch (IOException e) {
				throw new MojoFailureException(this, "Missing manifest "
						+ manifestLocation, "Error opening the manifest at '"
						+ manifestLocation + "'");
			}
		}
		return descriptor;
	}

	/**
	 * 
	 * @return
	 */
	public final File getLibrairiesLocation() {
		try {
			return tempLibrariesLocation == null
					|| tempLibrariesLocation.trim().isEmpty()
					|| project
							.getBasedir()
							.getCanonicalPath()
							.equals(new File(project.getBasedir(),
									tempLibrariesLocation).getCanonicalPath()) ? null
					: new File(project.getBasedir(), tempLibrariesLocation);
		} catch (IOException e) {
			// Ignore
		}
		return null;
	}

	/**
	 * 
	 * @return
	 */
	protected boolean mustPreservePDEPom() {
		return preservePdePom;
	}
	
}
